package com.liaoyin.travel.service.attendance;

import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.liaoyin.travel.view.mine.attendance.AttendanceStatisticsDetailedView;
import com.liaoyin.travel.view.mine.attendance.AttendanceStatisticsView;
import com.liaoyin.travel.vo.attendance.UserAttendanceRecordVO;
import com.liaoyin.travel.vo.request.MobileAttendanceStatRequestVO;
import com.liaoyin.travel.base.service.BaseService;
import com.liaoyin.travel.bean.UserInfo;
import com.liaoyin.travel.dao.UsersMapper;
import com.liaoyin.travel.dao.attendance.AttendanceRecordMapper;
import com.liaoyin.travel.dao.attendance.AttendanceStatisticsMapper;
import com.liaoyin.travel.dao.attendance.PunchInRecordMapper;
import com.liaoyin.travel.entity.FileUpload;
import com.liaoyin.travel.entity.UserTeam;
import com.liaoyin.travel.entity.Users;
import com.liaoyin.travel.entity.attendance.AttendanceSettings;
import com.liaoyin.travel.entity.attendance.AttendanceStatistics;
import com.liaoyin.travel.entity.attendance.PunchInRecord;
import com.liaoyin.travel.exception.BusinessException;
import com.liaoyin.travel.service.DictBasicService;
import com.liaoyin.travel.service.UsersService;
import com.liaoyin.travel.service.team.TeamWorkerService;
import com.liaoyin.travel.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @项目名：
 * @作者：lijing
 * @描述：出勤统计
 * @日期：Created in 2018/6/20 14:55
 */
@Service
public class AttendanceStatisticsService extends BaseService<AttendanceStatisticsMapper, AttendanceStatistics> {
   
	@Autowired
	private AttendanceSettingsService attendanceSettingsService;
	@Autowired
	private PunchInRecordService punchInRecordService;
	@Autowired
	private UsersService usersService;
    @Autowired
    private TeamWorkerService teamWorkerService;
    @Resource
    private UsersMapper usersMapper;
    @Resource
	private PunchInRecordMapper punchInRecordMapper;

    @Autowired
    private AttendanceRecordMapper attendanceRecordMapper;

    @Autowired
    private DictBasicService dictBasicService;

    @Autowired
    private AttendanceRecordService attendanceRecordService;

	/*****
	 * 
	     * @方法名：insertAttendanceStatistics
	     * @描述： 统计出勤
	     * @作者： lijing
	     * @日期： 2019年7月11日
	 */
	public void insertAttendanceStatistics(UserInfo user) {
		//首先获取考勤规则
		List<AttendanceSettings> list = this.attendanceSettingsService.selectAttendanceSettingsListOnMoble(user);
		//获取当日用户的打卡记录
		List<PunchInRecord> punList = this.punchInRecordService.selectPunchInRecordListToday(user.getId(),null);
		if(list !=null && list.size() >0) {
			AttendanceStatistics attStat = null;
			if(punList!=null && punList.size() >0) {
				//判断当日是否已经正常打卡了
				List<AttendanceStatistics> sList = selectAttendanceStatisticsByUserToday(user.getId(), null/*VariableConstants.STRING_CONSTANT_1*/);
				if (sList.size()>0){
				    return;
                }
				for(AttendanceSettings att:list) {
					for(PunchInRecord p:punList) {
						attStat = new AttendanceStatistics();
						//首先判断打卡的班次一直
						if(String.valueOf(att.getCheckShifts()).equals(String.valueOf(p.getCheckShifts()))) {
							//再判断打卡时间在班次允许的时间范围内
							if(DateUtil.isBeforeHHmmss(p.getCheckTime(),att.getCheckStartTime())) {
								/*if(sList !=null &&sList.size() >0) {
									break;
								}*//*else {*/
									//正常打卡-----每一天只记录一次考勤正常
									attStat.setWorkTime(p.getCheckTime());
									attStat.setWorkType((short)1);
									attStat.setCheckTime(att.getCheckEndTime());
									attStat.setCheckShifts(att.getCheckShifts());
								/*}*/
								
							}else if (DateUtil.isBelongHHmmss(p.getCheckTime(), att.getCheckStartTime(), att.getCheckEndTime())) {
								//迟到
								attStat.setWorkTime(p.getCheckTime());
								attStat.setWorkType((short)3);
								attStat.setCheckTime(att.getCheckEndTime());
								attStat.setCheckShifts(att.getCheckShifts());
							}
						} else if (!punList.stream().filter(pun->String.valueOf(pun.getCheckShifts()).equals(String.valueOf(att.getCheckShifts()))).findAny().isPresent()) {
							//缺卡
							attStat.setWorkTime(p.getCheckTime());
							attStat.setWorkType((short)4);
							attStat.setCheckTime(att.getCheckEndTime());
							attStat.setCheckShifts(att.getCheckShifts());
						} else {
							continue;
						}
						attStat.setCreatTime(new Date());
						attStat.setId(UUIDUtil.getUUID());
						attStat.setUserId(user.getId() == null ? user.getUserId():user.getId());
						this.mapper.insertSelective(attStat);
						attStat=null;
						break;
					}
					sList=null;
				}
			}else {
				//先判断是否有请假，若无就是矿工
				attStat = new AttendanceStatistics();
				attStat.setWorkType((short)5);
				attStat.setCreatTime(new Date());
				attStat.setWorkTime(new Date());
				attStat.setId(UUIDUtil.getUUID());
				attStat.setUserId(user.getId() == null ? user.getUserId():user.getId());
				this.mapper.insertSelective(attStat);
				attStat=null;
			}
		}
	}
	/****
	 * 
	     * @方法名：selectAttendanceStatisticsByUserToday
	     * @描述： 判断当日是否已经正常打卡了
	     * @作者： lijing
	     * @日期： 2019年7月11日
	 */
	public List<AttendanceStatistics> selectAttendanceStatisticsByUserToday(String userId,String workType) {
		
		List<AttendanceStatistics> list = this.mapper.selectAttendanceStatisticsByUserToday(userId, workType);
		return list;
	}
	
	
	/********************************APP************************************************/
	/*****
	 * 
	     * @方法名：selectAttendanceStatisticsMap
	     * @描述： 我的考勤统计
	     * @作者： lijing
	     * @日期： 2019年7月11日
	 */
	public List<AttendanceStatisticsView> selectAttendanceStatisticsMap(String checkendTime,String checkStartTime,String userId){
		
		UserInfo user = PartyUtil.getCurrentUserInfo();
		if(user == null ) {
			throw new BusinessException("not.login");
		}
		if(userId != null && !"".equals(userId)) {
			//判断是否有权限查询(是不是部门经理)
			if(user.getAssumeOffice()!=null && user.getAssumeOffice().intValue()==1) {
				List<UserTeam> usertramList = user.getUserTeamList();
		        if(usertramList==null || usertramList.size() == 0) {
		        	throw new BusinessException("team.is.null");
		        }
		        StringBuffer teamId = new StringBuffer();
		        for(UserTeam u:usertramList) {
		        	teamId.append(u.getTeamId()+",");
		        }
				boolean b = this.usersService.judgeThisUserInTeam(teamId.toString(), userId);
				if(!b) {
					throw new BusinessException("auth.is.erreo");
				}
			}
		}else {
			userId = user.getId();
		}
		List<AttendanceStatisticsView> list = this.mapper.selectAttendanceStatisticsMap(userId,checkendTime,checkStartTime);



		/*********************************************************************************************************************/

		HashMap<String,AttendanceStatisticsView> tempMap = new HashMap<String,AttendanceStatisticsView>();
		//去掉重复的key
		for(AttendanceStatisticsView a : list){
			String temp = a.getWorkType();
			//containsKey(Object key)该方法判断Map集合中是否包含指定的键名，如果包含返回true，不包含返回false
			//containsValue(Object value)该方法判断Map集合中是否包含指定的键值，如果包含返回true，不包含返回false
			if(tempMap.containsKey(temp)){
				AttendanceStatisticsView aa = new AttendanceStatisticsView();
				aa.setWorkType(temp);
				//合并相同key的value
				aa.setDisplayName(a.getDisplayName());
				aa.setNum(tempMap.get(temp).getNum() + a.getNum());
				//HashMap不允许key重复，当有key重复时，前面key对应的value值会被覆盖
				tempMap.put(temp,aa );
			}else{
				if(temp.equals("4")){
					MobileAttendanceStatRequestVO attendanceStatRequestVO = new MobileAttendanceStatRequestVO();
					attendanceStatRequestVO.setUserId(userId);
					attendanceStatRequestVO.setStartDate(null);
					List<Map<String,String>> lists = this.attendanceRecordService.getLackRecord(attendanceStatRequestVO);
					if(lists!=null && lists.size()>0){
						a.setNum(lists.size());
					}else{
						a.setNum(0);
					}
				}
				tempMap.put(temp,a );
			}
		}
		//去除重复key的list
		List<AttendanceStatisticsView> newList = new ArrayList<AttendanceStatisticsView>();
		for(String temp:tempMap.keySet()){
			newList.add(tempMap.get(temp));
		}



		/*********************************************************************************************************************/


        /*for (int i = 0; i < list.size();i++){
            for (int j = 0; j < list.size();j++){
                if (list.get(i).getWorkType().equals(list.get(j).getWorkType()) && i != j && list.size() > i && list.size() >j){
					*//*if (i == list.size()){
						continue;
					}*//*
                    AttendanceStatisticsView view = list.get(i);
                    AttendanceStatisticsView remove = list.remove(j);
                    view.setNum(remove.getNum()+view.getNum());
                }
            }
        }*/
        for (int i = 0; i < newList.size() ; i++){
        	if ("1".equals(newList.get(i).getWorkType())){
				newList.remove(i);
			}
		}
		List<PunchInRecord> punchInRecords = this.punchInRecordMapper.selectTeamPunchInRecordListByAtt(checkStartTime, checkendTime, userId);
		AttendanceStatisticsView view = new AttendanceStatisticsView();
		view.setWorkType("1");
		view.setDisplayName("出勤");
		view.setNum(punchInRecords.size());
		newList.add(view);
		return newList;
	}
	
	/*****
	 * 
	     * @方法名：selectAttendanceStatisticsDetailedList
	     * @描述： 我的考勤统计明细
	     * @作者： lijing
	     * @日期： 2019年7月11日
	 */
	public List<AttendanceStatisticsDetailedView> selectAttendanceStatisticsDetailedList(
			Integer num,Integer size,String checkendTime,String checkStartTime,String workType,String userId){
		
		UserInfo user = PartyUtil.getCurrentUserInfo();
		if(user == null ) {
			throw new BusinessException("not.login");
		}
		if(userId != null && !"".equals(userId)) {
			//判断是否有权限查询
			if(user.getAssumeOffice()!=null && user.getAssumeOffice().intValue()==1) {
				List<UserTeam> usertramList = user.getUserTeamList();
		        if(usertramList==null || usertramList.size() == 0) {
		        	throw new BusinessException("team.is.null");
		        }
		        StringBuffer teamId = new StringBuffer();
		        for(UserTeam u:usertramList) {
		        	teamId.append(u.getTeamId()+",");
		        }
				boolean b = this.usersService.judgeThisUserInTeam(teamId.toString(), userId);
				if(!b) {
					throw new BusinessException("auth.is.erreo");
				}
			}
		}else {
			userId = user.getId();
		}
		PageHelper.startPage(num,size);
		List<AttendanceStatisticsDetailedView> list = this.mapper.selectAttendanceStatisticsDetailedList(userId, checkendTime, checkStartTime, workType);
		if(list !=null && list.size() >0){
			list.stream().forEach((d) ->{
				if(d.getDetailedTime() !=null) {
					String week = DateUtil.getWeekCHN(d.getDetailedTime());
					d.setWeekNum(week);
				}
			});
		}
		return list;
	}


	/**
	 * @方法名：selectAttendanceStatisticsDetailedListByTime
	 * @描述： 查询部门下所有人打卡统计明细
	 * @作者： 周明智
	 * @日期： Created in 2019/8/13 10:15
	 */
	public List<AttendanceStatisticsDetailedView> selectAttendanceStatisticsDetailedListByTime(String  time){
		/** 获取当前登录用户信息*/
		UserInfo activeUser = PartyUtil.getCurrentUserInfo();
		Optional.ofNullable(activeUser).orElseThrow(() -> new BusinessException("not.login"));

		/** 判断是否有权限查询 */
		//职务
		Short assumeOffice = activeUser.getAssumeOffice();
		//部门信息
		List<UserTeam> usertramList = activeUser.getUserTeamList();
		if(usertramList==null || usertramList.size() == 0) {
			throw new BusinessException("team.is.null");
		}
		//职务为部门经理才能查询
		if(assumeOffice!=null && assumeOffice.intValue()==1) {
	        if(usertramList==null || usertramList.size() == 0) {
	        	throw new BusinessException("team.is.null");
	        }
	        StringBuffer teamId = new StringBuffer();
	        for(UserTeam u:usertramList) {
	        	teamId.append(u.getTeamId()+",");
	        }
			boolean b = this.usersService.judgeThisUserInTeam(teamId.toString(), activeUser.getId());
			if(!b) {
				throw new BusinessException("auth.is.erreo");
			}
		}

        StringBuffer teamId = new StringBuffer();
        for(UserTeam u:usertramList) {
        	teamId.append(u.getTeamId()+",");
        }
		System.err.println("teamId="+teamId);
		System.err.println("time="+time);
		List<AttendanceStatisticsDetailedView> attendanceStatisticsDetailedViews = this.mapper.selectAttendanceStatisticsDetailedListByTime(teamId.toString(), time);
		for (AttendanceStatisticsDetailedView attendanceStatisticsDetailedView : attendanceStatisticsDetailedViews) {
			Users users = new Users();
			System.err.println("users="+users);
			users.setFileUpload(FileUploadUtil.getFileUpload(attendanceStatisticsDetailedView.getUsersHeadPicId()));
			attendanceStatisticsDetailedView.setUsers(users);
		}
		System.err.println("attendanceStatisticsDetailedViews="+attendanceStatisticsDetailedViews);
		return attendanceStatisticsDetailedViews;
	}

    /**
     * @方法名：selectAttendanceStatistcsByTeamTime
     * @描述： 查询部门员工的出勤率及考勤异常的列表
     * @作者： 周明智
     * @日期： Created in 2019/9/2 10:23
     */
	public Map<String,Object> selectAttendanceStatistcsByTeamTime(String time){
		//查询部门下所有人打卡统计明细
        List<AttendanceStatisticsDetailedView> statisticsDetailedViews = this.selectAttendanceStatisticsDetailedListByTime(time);
        UserInfo activeUser = PartyUtil.getCurrentUserInfo();
		Optional.ofNullable(activeUser).orElseThrow(() -> new BusinessException("not.login"));
        //首先获取考勤规则
        List<AttendanceSettings> lists = this.attendanceSettingsService.selectAttendanceSettingsListOnMoble(activeUser);
        List<UserTeam> usertramList = activeUser.getUserTeamList();
        if(usertramList==null || usertramList.size() == 0) {
            throw new BusinessException("team.is.null");
        }
        StringBuffer teamId = new StringBuffer();
        for(UserTeam u:usertramList) {
            teamId.append(u.getTeamId()+",");
        }
        List<Users> users = teamWorkerService.selectUsersListByTeamId(teamId.toString());

        List<AttendanceStatisticsDetailedView> list = new ArrayList<>();


		//List<PunchInRecord> punchInRecords1 = this.punchInRecordService.selectTeamPunchInRecordList(time);

        for (Users u : users) {

			SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

			if (lists != null && lists.size() > 0) {
				/**
				 * 根据用户及时间查询考勤的状态
				 */
				AttendanceStatisticsDetailedView attendanceStatisticsDetailedView = new AttendanceStatisticsDetailedView();
				System.err.println("u.getId() = "+ u.getId());
				System.err.println("time = "+ time);
				UserAttendanceRecordVO userAttendanceRecordVO = attendanceRecordMapper.getUserAttendanceRecordVO(u.getId(),time);
				FileUpload fileUpload = FileUploadUtil.getFileUpload(u.getHeadPicId() != null ? u.getHeadPicId() : null);
				attendanceStatisticsDetailedView.setUsersId(u.getId());
				attendanceStatisticsDetailedView.setUsersHeadPicId(fileUpload!=null ? fileUpload.getUrl():null).setUsersNickName(u.getNickName()).setUserWorkerNum(u.getWorkerNum());
				try{
					if(userAttendanceRecordVO!=null){
						/*if(StringUtil.isNotEmpty(userAttendanceRecordVO.getFinalState()) && (userAttendanceRecordVO.getFinalState().equals("6") || userAttendanceRecordVO.getFinalState().equals("12"))){
							attendanceStatisticsDetailedView.setWorkType(userAttendanceRecordVO.getFinalState());
							attendanceStatisticsDetailedView.setWorkTypeDisplay(dictBasicService.getDisplayByCodeVal("attendanceStatus",userAttendanceRecordVO.getFinalState()));
						}else */
						if(StringUtil.isNotEmpty(userAttendanceRecordVO.getFinalState())){
							//attendanceStatisticsDetailedView.setCheckTime(sdf.parse(userAttendanceRecordVO.getEndTime()));
							//attendanceStatisticsDetailedView.setDetailedTime(sdf.parse(userAttendanceRecordVO.getEndTime()));
							attendanceStatisticsDetailedView.setWorkType(userAttendanceRecordVO.getFinalState());
							attendanceStatisticsDetailedView.setWorkTypeDisplay(dictBasicService.getDisplayByCodeVal("attendanceStatus",userAttendanceRecordVO.getFinalState()));
						}else if(StringUtil.isNotEmpty(userAttendanceRecordVO.getOutState()) && StringUtil.isNotEmpty(userAttendanceRecordVO.getInState())){
							System.err.println("users = " + u);
							System.err.println("userAttendanceRecordVO="+userAttendanceRecordVO);
							System.err.println("userAttendanceRecordVO.getInState()="+userAttendanceRecordVO.getInState());
                            if(userAttendanceRecordVO.getInState().equals("2") && userAttendanceRecordVO.getInState().equals("5") && userAttendanceRecordVO.getInState().equals("6")){
                                //attendanceStatisticsDetailedView.setDetailedTime(sdf.parse(userAttendanceRecordVO.getOutTime()));
                            }
							//attendanceStatisticsDetailedView.setCheckTime(sdf.parse(userAttendanceRecordVO.getEndTime()));
							attendanceStatisticsDetailedView.setWorkType(userAttendanceRecordVO.getOutState());
							attendanceStatisticsDetailedView.setWorkTypeDisplay(dictBasicService.getDisplayByCodeVal("attendanceStatus",userAttendanceRecordVO.getOutState()));
						}else if(StringUtil.isNotEmpty(userAttendanceRecordVO.getInState())){
						    if(userAttendanceRecordVO.getInState().equals("2") && userAttendanceRecordVO.getInState().equals("5") && userAttendanceRecordVO.getInState().equals("6")){
                                attendanceStatisticsDetailedView.setDetailedTime(sdf.parse(userAttendanceRecordVO.getInTime()));
                            }
							//attendanceStatisticsDetailedView.setCheckTime(sdf.parse(userAttendanceRecordVO.getStartTime()));
							attendanceStatisticsDetailedView.setWorkType(userAttendanceRecordVO.getInState());
							attendanceStatisticsDetailedView.setWorkTypeDisplay(dictBasicService.getDisplayByCodeVal("attendanceStatus",userAttendanceRecordVO.getInState()));
						}else{
							attendanceStatisticsDetailedView.setWorkType("2");
							attendanceStatisticsDetailedView.setWorkTypeDisplay(dictBasicService.getDisplayByCodeVal("attendanceStatus","2"));
						}

					}else{
						UserAttendanceRecordVO attendanceTime = attendanceRecordMapper.getUserAttendanceTime(u.getId());
						if(attendanceTime!=null){
							//attendanceStatisticsDetailedView.setCheckTime(sdf.parse(attendanceTime.getStartTime()));
							//attendanceStatisticsDetailedView.setDetailedTime(null);
						}
						attendanceStatisticsDetailedView.setWorkType("5");
						attendanceStatisticsDetailedView.setWorkTypeDisplay(dictBasicService.getDisplayByCodeVal("attendanceStatus","5"));
					}
				}catch (Exception e){
					e.printStackTrace();
				}

				/**
				 * 如果有请假、补卡、外出、请假+补卡，排除异常
				 */
				List<String> ignoreStatus = Lists.newArrayList("6","9","11","12");
				if(!ignoreStatus.contains(attendanceStatisticsDetailedView.getWorkType())){
					list.add(attendanceStatisticsDetailedView);
				}
            }
        }

        for (int i = 0;i<list.size();i++){
        	for (int j = 0; j <list.size() ;j++){
				AttendanceStatisticsDetailedView view = list.get(i);
				AttendanceStatisticsDetailedView view1 = list.get(j);
				if(view.getUsersId().equals(view1.getUsersId())){
					if( Integer.valueOf(view.getWorkType()) > Integer.valueOf(view1.getWorkType())) {
						if (view.getCheckShifts() != null && !"".equals(view) && view1.getCheckShifts() != null
								&& !"".equals(view1.getCheckShifts()) && view.getCheckShifts() <view1.getCheckShifts() ) {
							list.remove(j);
						}
					} else if ( Integer.valueOf(view.getWorkType()) < Integer.valueOf(view1.getWorkType())){
						if (view.getCheckShifts() != null && !"".equals(view) && view1.getCheckShifts() != null
								&& !"".equals(view1.getCheckShifts()) && view.getCheckShifts() <view1.getCheckShifts() ) {
							list.remove(j);
						}
					} else if ( Integer.valueOf(view.getWorkType()).equals(Integer.valueOf(view1.getWorkType())) && i!=j){
						list.remove(j);
					}
				}
			}
		}

        int attendanctCnt = 0;//attendanceRecordMapper.getAttenceCnt(users,time);

        for(AttendanceStatisticsDetailedView view:list){
        	if(view.getWorkType().equals("1")||view.getWorkType().equals("6")||view.getWorkType().equals("9")||view.getWorkType().equals("11")||view.getWorkType().equals("12")){
				attendanctCnt++;
			}
		}

        Float percentage = ((float)attendanctCnt/(float) users.size())*100;
        Map map = new HashMap<>();
        map.put("percentage",percentage);
        map.put("list",list);
        return map;
    }
}
